余烬缀记

JavaScript 继承和实例化

edited on:

# 实例化

const isFunction = (fn) => typeof fn === 'function'
function getInstance(target, ...arg) {
    if (!isFunction(target)) throw new TypeError('target is not a function')
    const instance = Object.create(target.prototype)
    target.apply(instance, arg)
    return instance
}

# 继承

const isFunction = (fn) => typeof fn === 'function'

function inherit(subType, superType) {
    if (!isFunction(subType)) throw new TypeError('subType is not a function')
    if (!isFunction(superType)) throw new TypeError('superType is not a function')
    const prototype = Object.create(superType.prototype)
    prototype.constructor = subType
    subType.prototype = prototype
}

使用Object.create创建一个引用superType.prototype的对象是这一步的关键

为什么不用setPrototypeOf或者直接更改__protp__

摘抄自MDN

由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.__proto__ = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]

所以使用Object.create创建一个引用它的新对象是比较合适的写法

结束语:因为没复习的原因好多记忆都开始遗忘,再不回忆下就没了。像这种模拟new关键字和extends关键字行为的情况在现代浏览器支持下已经荡然无存了。